package com.heima.article.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.article.dto.ArticleDto;
import com.heima.article.dto.ArticleHomeDto;
import com.heima.article.dto.ArticleInfoDto;
import com.heima.article.entity.ApArticle;
import com.heima.article.entity.ApArticleContent;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.IApArticleContentService;
import com.heima.article.service.IApArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.service.IAsyncService;
import com.heima.common.dto.ResponseResult;
import com.heima.common.enums.AppHttpCodeEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 文章信息表，存储已发布的文章 服务实现类
 * </p>
 *
 * @author mcm
 * @since 2022-04-13
 */
@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements IApArticleService {

    @Autowired
    private IApArticleContentService contentService;

    @Autowired
    private IAsyncService asyncService;


    @Override
    public ResponseResult<Long> saveArticle(ArticleDto dto) {

        ApArticle apArticle = new ApArticle();
        BeanUtils.copyProperties(dto, apArticle);

        //判断新增还是修改
        if (dto.getId() == null) {
            //保存文章
            apArticle.setCreatedTime(new Date());
            this.save(apArticle);
            //保存文章内容
            ApArticleContent content = new ApArticleContent();
            content.setArticleId(apArticle.getId());
            content.setContent(dto.getContent());
            contentService.save(content);

            //生成静态页面 异步线程
            System.out.println(Thread.currentThread().getName() + " 开始调用生成静态html服务...");
            asyncService.createHtml(apArticle, dto.getContent());
            System.out.println(Thread.currentThread().getName() + " 生成静态html调用结束");

            asyncService.createIndex(apArticle);


            return ResponseResult.okResult(apArticle.getId());

        } else {
            //修改文章
            this.updateById(apArticle);
            //修改内容
            LambdaUpdateWrapper<ApArticleContent> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(ApArticleContent::getArticleId, dto.getAuthorId());
            updateWrapper.set(ApArticleContent::getContent, dto.getContent());
            contentService.update(updateWrapper);

            //生成静态页面 异步线程
            System.out.println(Thread.currentThread().getName() + " 开始调用生成静态html服务...");
            asyncService.createHtml(apArticle, dto.getContent());
            System.out.println(Thread.currentThread().getName() + " 生成静态html调用结束");

            asyncService.updateIndex(apArticle);
            return ResponseResult.okResult(apArticle.getId());
        }


    }

    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 加载文章列表
     *
     * @param dto
     * @param type 0: 默认首页最新文章  1: 更多文章-下一页
     * @return
     */
    @Override
    public ResponseResult loadArticle(ArticleHomeDto dto, Integer type) {
        // 判断是否是首页加载数据,如果是首页的话,先从redis中查询数据
        if (dto.getLoaddir() == 1) {
            //是首页或频道首页，从redis中查询数据，按照分值从大到小排序
            String key = "first_page_article_" + dto.getChannelId();
            long start = 0;
            long end = dto.getSize() - 1;
            Set<String> strings = redisTemplate.opsForZSet().reverseRange(key, start, end);

            ArrayList<ApArticle> articles = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(strings)) {
                for (String string : strings) {
                    ApArticle article = JSON.parseObject(string, ApArticle.class);
                    articles.add(article);
                }
            }
            if (articles.size() >= dto.getSize()) {
                return ResponseResult.okResult(articles);
            } else {
                //查找最新的一页多数据
                LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.orderByDesc(ApArticle::getPublishTime);
                // 已下架和已删除的文章需要排除
                queryWrapper.eq(ApArticle::getIsDelete, false);
                queryWrapper.eq(ApArticle::getIsDown, false);
                //构建分页条件，查文章
                IPage<ApArticle> page = new Page<>(1, dto.getSize() + articles.size());
                IPage<ApArticle> iPage = this.page(page, queryWrapper);
                List<ApArticle> records = iPage.getRecords();
                if (articles.size() == 0) {
                    return ResponseResult.okResult(records);
                }
                //排除重复的数据
                Iterator<ApArticle> iterator = records.iterator();
                while (iterator.hasNext()) {
                    ApArticle next = iterator.next();
                    for (ApArticle article : articles) {
                        if (next.getId().equals(article.getId())) {
                            iterator.remove();
                        }
                    }
                }
                System.out.println(records);
                System.out.println("=======");
                //合并数据
                System.out.println(articles);
                articles.addAll(records);
                return ResponseResult.okResult(articles);
            }

        }

        //构建查询条件
        LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
        if (dto.getChannelId() != null && dto.getChannelId() != 0) {
            queryWrapper.eq(ApArticle::getChannelId, dto.getChannelId());
        }
        //查找最新的
        if (type == 0) {
            queryWrapper.gt(ApArticle::getPublishTime, dto.getMaxTime());
        }
        //下一页
        if (type == 1) {
            queryWrapper.lt(ApArticle::getPublishTime, dto.getMinTime());
        }
        // 已下架和已删除的文章需要排除
        queryWrapper.eq(ApArticle::getIsDelete, false);
        queryWrapper.eq(ApArticle::getIsDown, false);
        // 文章列表按照发布时间倒序排列
        queryWrapper.orderByDesc(ApArticle::getPublishTime);
        //构建分页条件
        IPage<ApArticle> page = new Page<>(1, dto.getSize());
        IPage<ApArticle> iPage = this.page(page, queryWrapper);
        return ResponseResult.okResult(iPage.getRecords());
    }

    @Override
    public ResponseResult loadArticleInfo(ArticleInfoDto dto) {
        //参数校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //查找文章和内容
        ApArticle apArticle = this.getById(dto.getArticleId());
        LambdaQueryWrapper<ApArticleContent> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApArticleContent::getArticleId, dto.getArticleId());
        ApArticleContent content = contentService.getOne(queryWrapper);
        //返回map
        HashMap<String, Object> map = new HashMap();
        map.put("config", apArticle);
        map.put("content", content);
        return ResponseResult.okResult(map);
    }

}
